package com.huifer.wgx.service.impl;

import com.huifer.wgx.model.PersonnelEntity;
import com.huifer.wgx.model.ProjectEntity;
import com.huifer.wgx.model.WorkEntity;
import com.huifer.wgx.repository.PersonnelRepository;
import com.huifer.wgx.repository.ProjectRepository;
import com.huifer.wgx.repository.WorkRepository;
import com.huifer.wgx.service.WorkService;
import java.sql.Timestamp;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

/**
 * <p>Title : WorkServiceImpl </p>
 * <p>Description : </p>
 *
 * @author huifer
 * @date 2019-03-18
 */
@Service
public class WorkServiceImpl implements WorkService {

    @Autowired
    private WorkRepository workRepository;

    @Autowired
    private PersonnelRepository personnelRepository;

    @Autowired
    private ProjectRepository projectRepository;


    /**
     * 创建一个工程
     *
     * @param projectName 项目名称
     * @param workName 工程名称
     * @param startTime 开始时间
     * @param personnelName 负责人名称
     * @return 工程 {@link WorkEntity}
     */
    @Override
    public WorkEntity saveWork(String projectName, String workName, Timestamp startTime,
            String personnelName) {
        try {

            PersonnelEntity personnelList = personnelRepository
                    .findByPersonnelName(personnelName);
            ProjectEntity projectEntity = projectRepository.findByProjectName(projectName);

            WorkEntity byWorkName = workRepository.findByWorkName(workName);

            if (personnelList != null && projectEntity != null & byWorkName == null) {

                WorkEntity saveWork = new WorkEntity();
                saveWork.setProjectId(projectEntity.getProjectId());
                saveWork.setWorkName(workName);
                saveWork.setWorkStartTime(startTime);
                saveWork.setPersonnelId(personnelList.getPersonnelId());

                return workRepository.save(saveWork);

            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 更新项目完成情况
     *
     * @param workName 工程名称
     * @param endTime 结束时间
     * @return 工程 {@link WorkEntity}
     */
    @Override
    public WorkEntity updateWork(String workName, Timestamp endTime) {

        try {
            WorkEntity byWorkName = workRepository.findByWorkName(workName);
            if (byWorkName != null) {

                byWorkName.setWorkEndTime(endTime);
                // 计算工期
                int days = ((int) (endTime.getTime() / 1000) - (int) (byWorkName.getWorkStartTime()
                        .getTime() / 1000)) / 3600 / 24;

                byWorkName.setWorkExecutionTime(String.valueOf(days));

                return workRepository.save(byWorkName);

            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 查询所有工程
     *
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 工程列表{@link WorkEntity}
     */
    @Override
    public Page<WorkEntity> findAll(Integer pageNum, Integer pageSize) {
        Sort sort = new Sort(Direction.DESC, "workId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        Page<WorkEntity> all = workRepository.findAll(pageable);
        return all;
    }

    /**
     * 根据项目id查询工程
     *
     * @param projectId 项目id
     * @return 工程列表{@link WorkEntity}
     */
    @Override
    public Page<WorkEntity> findWorkByProjectId(Long projectId, Integer pageNum, Integer pageSize) {

        Specification<WorkEntity> spec = (Specification<WorkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            Predicate pf1 = criteriaBuilder
                    .equal(root.get("projectId"), projectId);
            return pf1;
        };
        Page<WorkEntity> all = getWorkEntities(pageNum, pageSize, spec);
        return all;
    }

    private Page<WorkEntity> getWorkEntities(Integer pageNum, Integer pageSize,
            Specification<WorkEntity> spec) {
        Sort sort = new Sort(Direction.DESC, "workId");
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize, sort);
        return workRepository.findAll(spec, pageable);
    }

    /**
     * 根据项目名称查询工程
     *
     * @param projectName 项目名称
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 工程列表{@link WorkEntity}
     */
    @Override
    public Page<WorkEntity> findWorkByProjectName(String projectName, Integer pageNum,
            Integer pageSize) {
        try {

            ProjectEntity byProjectName = projectRepository.findByProjectName(projectName);

            if (byProjectName != null) {

                Specification<WorkEntity> spec = (Specification<WorkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
                    Predicate projectId = criteriaBuilder
                            .equal(root.get("projectId"), byProjectName.getProjectId());
                    return projectId;
                };
                Page<WorkEntity> all = getWorkEntities(pageNum, pageSize, spec);
                return all;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据项目负责人查询工程
     *
     * @param pName 负责人名称
     * @param pageNum 页面号
     * @param pageSize 页面大小
     * @return 工程列表{@link WorkEntity}
     */
    @Override
    public Page<WorkEntity> findWorkByPersonnel(String pName, Integer pageNum, Integer pageSize) {
        try {

            PersonnelEntity byPersonnelName = personnelRepository.findByPersonnelName(pName);
            if (byPersonnelName != null) {

                Specification<WorkEntity> spec = (Specification<WorkEntity>) (root, criteriaQuery, criteriaBuilder) -> {
                    Predicate projectId = criteriaBuilder
                            .equal(root.get("personnelId"), byPersonnelName.getPersonnelId());
                    return projectId;
                };

                Page<WorkEntity> all = getWorkEntities(pageNum, pageSize, spec);
                return all;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 更新工程名称
     *
     * @param workId 工程id
     * @param newWorkName 新工程名称
     * @return 工程
     */
    @Override
    public WorkEntity updateWork(Long workId, String newWorkName) {
        try {
            WorkEntity workEntity = workRepository.findById(workId).get();
            if (workEntity != null) {
                workEntity.setWorkName(newWorkName);
                WorkEntity save = workRepository.save(workEntity);
                return save;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 更新工程名称
     *
     * @param oldWorkName 旧工程名称
     * @param newWorkName 新工程名称
     * @return 工程
     */
    @Override
    public WorkEntity updateWork(String oldWorkName, String newWorkName) {
        try {
            WorkEntity byWorkName = workRepository.findByWorkName(oldWorkName);
            if (byWorkName != null) {
                byWorkName.setWorkName(newWorkName);
                WorkEntity save = workRepository.save(byWorkName);
                return save;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除工程
     *
     * @param workId 工程id
     * @return 工程
     */
    @Override
    public WorkEntity deleteWork(Long workId) {
        try {
            WorkEntity workEntity = workRepository.findById(workId).get();
            if (workEntity != null) {
                workRepository.delete(workEntity);
                return workEntity;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 删除工程
     *
     * @param workName 工程名称
     * @return 工程
     */
    @Override
    public WorkEntity deleteWork(String workName) {
        try {
            WorkEntity byWorkName = workRepository.findByWorkName(workName);
            if (byWorkName != null) {
                workRepository.delete(byWorkName);
                return byWorkName;
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
